﻿using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;

using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using ConfApp.Models;
using System.Text;
using ConfApp.Models.Dto;
using Newtonsoft.Json;

namespace ConfApp.Services.ConfDataService
{
    public class ConfDataStore : Store, IConfDataStore
    {
        private const string FavouritesStore = "FavouritesStore";
        private const string Store = "ConfDataStore";

        private ConfAppModel _model;

        public int Version { get { return _model.Version??0; } }

        public IEnumerable<Session> GetSessionsByDayIndexAndTrack(int index, string track)
        {
            return string.IsNullOrEmpty(track) ?
                _model.Sessions.Values.Where(s => s.Slot.Day.Index == index):
                _model.Sessions.Values.Where(s => s.Slot.Day.Index == index && s.Track.Code==track);
        }

        public IEnumerable<Session> GetSessionsByTrack(string track)
        {
            return _model.Sessions.Values.Where(s=>s.Track.Code == track);
        }

        public IEnumerable<Session> GetFavouriteSessions()
        {
            return _model.Sessions.Values.Where(s => s.IsFavourite);
        }

        public IEnumerable<Session> GetNextSessions()
        {
            var now = Time.Now;
            var nextSlots =  _model.Slots.Values.Where(s=>s.Start>now).OrderBy(s=>s.Start);
            foreach (var nextSlot in nextSlots)
            {
                var sessions = _model.Sessions.Values.Where(s => s.IsScheduled && s.Slot.ID == nextSlot.ID);
                if (sessions.Count() > 0) return sessions;
            }
            return Enumerable.Empty<Session>();
        }

        public Session FindSession(int id)
        {
            return _model.Sessions[id];
        }

        public IEnumerable<Speaker> GetSpeakers()
        {
            return _model.Speakers.Values;
        }

        public IEnumerable<Track> GetTracks()
        {
            return _model.Tracks.Values;
        }

        public Speaker FindSpeaker(int id)
        {
            return _model.Speakers[id];
        }

        public ConfDataStore()
        {

            var favourites = GetDataFromJson<List<int>>(FavouritesStore);

            _model =  ConfAppModel.FromDto(GetDataFromJson<ConfAppModelDto>(Store));
            if(!_model.IsInitialized)
            {
                _model = ConfAppModel.FromDto(LoadDefaultModel());
            }

            foreach (var session in _model.Sessions.Values)
            {
                if (favourites.Contains(session.ID)) session.IsFavourite = true;
            }
        }

        private ConfAppModelDto LoadDefaultModel()
        {
            using (var str = new StreamReader(Application.GetResourceStream(new Uri("/ConfApp;component/Resources/Data/data.json", UriKind.Relative)).Stream))
            {
                return JsonConvert.DeserializeObject<ConfAppModelDto>(str.ReadToEnd());
            }
        }

        private static string GetSpeakerPictureStoreName(Speaker speaker)
        {
            return string.Format("{0}_{1}", Store, speaker.ID);
        }

        public bool SaveConfData(ConfAppModelDto confData)
        {
            if (confData.Version != 0)
            {
                _model = ConfAppModel.FromDto(confData);
                var favourites = GetDataFromJson<List<int>>(FavouritesStore);
                foreach (var speaker in _model.Speakers.Values)
                {
                    if(speaker.Picture!=null) 
                        StoreBytes(GetSpeakerPictureStoreName(speaker),speaker.Picture);
                }
                foreach (var session in _model.Sessions.Values)
                {
                    if (favourites.Contains(session.ID)) session.IsFavourite = true;
                }                
                StoreDataToJson(Store, confData);
                return true;
            }
            return false;
        }

        public void SaveFavouritesStore()
        {
            StoreDataToJson(FavouritesStore,_model.Sessions.Values.Where(s=>s.IsFavourite).Select(s=>s.ID).ToList());
        } 
    }
}